<?php

use seecms\db\SeeDbException;
use seecms\See;
use seecms\SeeException;
use seecms\SeeLang;

if (!function_exists('see_root')) {
    /**
     * see目录
     * @return string
     */
    function see_root(): string
    {
        return __DIR__;
    }
}

if (!function_exists('see_version')) {
    /**
     * 版本号
     * @return string
     */
    function see_version(): string
    {
        return 'v2.0.0';
    }
}

if (!function_exists('see_config')) {
    /**
     * 获取配置,支持.  lang.site
     * @param $field
     * @return array|mixed
     */
    function see_config($field = null)
    {
        if (is_null($field)) {
            return '';
        }

        $keys = explode('.', $field);

        $len = count($keys);
        $current = See::config()->value(array_shift($keys));
        if ($len === 1) {
            return $current;
        }

        foreach ($keys as $part) {
            if (!isset($current[$part])) {
                return '';
            }
            $current = $current[$part];
        }

        return $current;
    }
}

if (!function_exists('make_lang_json')) {
    /**
     * 生成前端js语言包
     * @param $lang
     * @return void
     * @throws SeeException
     */
    function make_lang_json($lang)
    {
        $json = see_config('lang.static.dir');
        if (!is_dir($json) && !mkdir($json)) {
            SeeException::throw('生成前端语言包文件失败,请手动创建目录:' . $json);
        }

        See::lang()->switchLangSet($lang);
        file_put_contents($json . $lang . '.js', 'const lang = ' . json_encode(See::lang()->getData($lang), JSON_UNESCAPED_UNICODE));
    }
}

if (!function_exists('auth_route')) {
    /**
     * 权限路由
     * @param $route
     * @param ...$_
     * @return string
     */
    function auth_route($route, ...$_): string
    {
        $other = implode('/', $_);
        if ($other) {
            $other = '/' . trim($other, '/');
        }

        return '/admin/' . trim($route, '/') . $other;
    }
}

if (!function_exists('__')) {
    /**
     * 语言函数
     * @param $field
     * @return array|mixed|string|string[]|null
     */
    function __($field)
    {
        return SeeLang::instance()->get($field);
    }
}

if (!function_exists('load_asset')) {
    /**
     * 加载cms资源
     * @param $src
     * @return string
     */
    function load_asset($src): string
    {
        $cms = See::config()->vendor->assetStatic();

        return $cms . '/' . trim($src, '/');
    }
}

if (!function_exists('load_lib')) {
    /**
     * 加载扩展库
     * @param $src
     * @return string
     */
    function load_lib($src): string
    {
        // 添加引入静态资源函数
        $lib = See::config()->vendor->assetLib();

        return $lib . '/' . trim($src, '/');
    }
}

if (!function_exists('view_path')) {
    /**
     * 视图文件地址
     * @param $src
     * @return string
     */
    function view_path($src): string
    {
        if (is_file($src)) {
            return $src;
        }

        $src = $src . '.php';
        if (is_file($src)) {
            return $src;
        }

        return dirname(__FILE__) . '/view/' . $src;
    }
}

if (!function_exists('parse_db_table')) {

    /**
     * 解析数据表格
     * @param string $table
     * @return array
     */
    function parse_db_table(string $table): array
    {
        $columns = [];
        $dictionary = [];

        try {
            $attrs = See::db()->query("show full columns from $table");

            foreach ($attrs as $attr) {
                $field = $attr['Field'];
                $comment = $attr['Comment'];
                if (in_array($field, ['updated_at', 'deleted_at'])) {
                    continue;
                }
                if ($comment) {
                    $comments = explode(' ', $comment);
                    $dictionary[$field] = current($comments);
                }

                $columns[] = $field;
            }

        } catch (SeeDbException|\Throwable $exception) {

        }

        return compact('columns', 'dictionary');
    }
}

if (!function_exists('preprocessing_sql')) {
    /**
     * @param string $sql
     * @return array
     */
    function preprocessing_sql(string $sql): array
    {
        if (empty($sql)) {
            return [];
        }

        // 行注释
        $sql = preg_replace('/--.*?$|#.*?$/m', '', $sql);
        // 块注释
        $sql = preg_replace('/\/\*.*?\*\//s', '', $sql);
        $sql = trim($sql);

        // 分割SQL语句
        $queries = array_filter(
            explode(';', $sql),
            function ($query) {
                return trim($query) !== '';
            }
        );

        return $queries ?: [];
    }
}

if (!function_exists('ck_directory')) {
    /**
     * 检查并且创建目录,并且是否可写
     * @param ...$_
     * @return mixed
     * @throws SeeException
     */
    function ck_directory(...$_)
    {
        $dir = array_reduce($_, function ($dir, $item) {
            $extension = pathinfo($item, PATHINFO_EXTENSION);
            if ($extension) {
                $item = dirname($item);
            }
            return $dir . rtrim($item, '/') . '/';
        });

        if (!is_dir($dir) && !mkdir($dir, 0777, true)) {
            throw new SeeException('Failed to create directory:' . $dir);
        }

        if (!is_writeable($dir)) {
            throw new SeeException('The target directory is not writable:' . $dir);
        }

        return $dir;
    }
}